#ifndef _DEV_STREAM_H_
#define _DEV_STREAM_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <types.h>
#include "device.h"
#include <kfifo.h>
#include "softtimer.h"

#define STREAM_DEFAULT_CACHE_SIZE   256

struct stream_device;

#define to_dev(stream_dev) (&(stream_dev)->dev)
#define to_stream_dev(dev) container_of(dev, struct stream_device, dev)

struct stream_operations
{
    int (*init)(struct stream_device *);
    int (*open)(struct stream_device *);
    int (*ctrl)(struct stream_device *, u32 cmd, void *args);
    void (*release)(struct stream_device *);

    /* read & write directly */
    ssize_t(*ioread)(struct stream_device *, const ev_buf_t *buf, size_t n);
    ssize_t (*iowrite)(struct stream_device *, const ev_buf_t *buf, size_t n);

    void (*on_poll_in)(struct stream_device *);
    void (*on_poll_out)(struct stream_device *);
    void (*on_eof)(struct stream_device *);
};

struct stream_device
{
    device_t            dev;

    const struct stream_operations *ops;

    struct soft_timer   frame_tmr;
    u16                 frame_to;

    u32                 rxcache_size;
    struct kfifo_ptr    rxcache;
    u32                 txcache_size;
    struct kfifo_ptr    txcache;
};

int stream_poll_read(struct stream_device *stream_dev);
int stream_device_register(struct stream_device *, const char *, void *);
void stream_device_unregister(struct stream_device *);

#ifdef __cplusplus
}
#endif
#endif
